package com.alinesno.cloud.common.core.rest;

import java.util.List;
import java.util.Optional;

import org.apache.commons.lang.builder.ToStringBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;

import com.alinesno.cloud.common.core.orm.entity.BaseEntity;
import com.alinesno.cloud.common.core.services.IBaseService;
import com.alinesno.cloud.common.facade.pageable.RestPage;
import com.alinesno.cloud.common.facade.wrapper.RestWrapper;

/**
 * 对外rest接口基类
 *
 * @author LuoAnDong
 * @since 2018年11月21日 上午10:46:56
 */
public abstract class BaseRestController<E extends BaseEntity, S extends IBaseService<?, E, String>> extends SuperRestController {

	private static final Logger log = LoggerFactory.getLogger(BaseRestController.class);

	@Autowired
	protected S service;

	@GetMapping("findAll")
	public List<E> findAll() {
		return service.findAll();
	}

	@PostMapping("findAllBySort")
	public List<E> findAll(@RequestBody Sort sort) {
		return service.findAll(sort);
	}

	@PostMapping("findAllById")
	public List<E> findAllById(@RequestBody Iterable<String> ids) {
		log.debug("ids = {}", ids);
		return service.findAllById(ids);
	}

	@PostMapping("saveAll")
	public List<E> saveall(@RequestBody Iterable<E> entities) {
		return service.saveAll(entities);
	}

	@PostMapping("saveAndFlush")
	public E saveAndFlush(@RequestBody E entity) {
		return service.saveAndFlush(entity);
	}

	@PostMapping("deleteInBatch")
	public void deleteInBatch(@RequestBody Iterable<E> entities) {
		service.deleteInBatch(entities);
	}

	@GetMapping("deleteAllInBatch")
	public void deleteAllInBatch() {
		service.deleteAllInBatch();
	}

	@GetMapping("getOne")
	public E getOne(String id) {
		log.debug("id = {}", id);
		return service.getOne(id);
	}

	@PostMapping("findAllByPageable")
	public RestPage<E> findAll(@RequestBody RestPage<E> restPage) {

		log.debug("pageable = {}", ToStringBuilder.reflectionToString(restPage));

		Page<E> page = service.findAll(PageRequest.of(restPage.getNumber(), restPage.getSize() , restPage.getSort()));

		log.debug("page = {}", ToStringBuilder.reflectionToString(page));
		log.debug("content = {}", ToStringBuilder.reflectionToString(page.getContent()));

		for (E e : page.getContent()) {
			log.debug("e = {}", ToStringBuilder.reflectionToString(e));
		}

		return new RestPage<E>(page);
	}

	@PostMapping("save")
	public E save(@RequestBody E entity) {
		return service.save(entity);
	}

	@GetMapping("findById")
	public Optional<E> findById(String id) {
		return service.findById(id);
	}

	@GetMapping("existsById")
	public boolean existsById(String id) {
		return service.existsById(id);
	}

	@GetMapping("count")
	public long count() {
		return service.count();
	}

	@GetMapping("deleteById")
	public void deleteById(String id) {
		service.deleteById(id);
	}
	
	@PostMapping("deleteByIds")
	public void deleteByIds(@RequestBody String[] ids) {
		service.deleteByIds(ids) ; 
	}

	@PostMapping("delete")
	public void delete(@RequestBody E entity) {
		service.delete(entity);
	}

	@PostMapping("deleteAllByIterable")
	public void deleteAll(@RequestBody Iterable<E> entities) {
		service.deleteAll(entities);
	}

	@PostMapping("deleteAll")
	public void deleteAll() {
		service.deleteAll();
	}

	@PostMapping("findOneByWrapper")
	public Optional<E> findOne(@RequestBody RestWrapper restWrapper) {
		log.debug("restWrapper = {}", ToStringBuilder.reflectionToString(restWrapper));
		return service.findOne(SpecificationBuilder(restWrapper));
	}

	@PostMapping("findAllByWrapper")
	public List<E> findAll(@RequestBody RestWrapper restWrapper) {
		log.debug("restWrapper = {}", ToStringBuilder.reflectionToString(restWrapper));
		return service.findAll(SpecificationBuilder(restWrapper));
	}

	@PostMapping("findAllByWrapperAndPageable")
	public RestPage<E> findAllByWrapperAndPageable(@RequestBody RestWrapper restWrapper) {
		log.debug("entity wrapper = {} , pageable = {}", restWrapper);

		RestPage<?> restPage = restWrapper.getPageable();
		Page<E> page = service.findAll(SpecificationBuilder(restWrapper), PageRequest.of(restPage.getNumber(), restPage.getSize(), restPage.getSort()));

		return new RestPage<E>(page);
	}

	/**
	 * 更新实体状态 
	 * @param id
	 * @return
	 */
	@GetMapping("modifyHasStatus")
	boolean modifyHasStatus(@RequestParam("id") String id) {
		return service.modifyHasStatus(id);
	}
	

	@GetMapping("findAllByApplicationId")
	List<E> findAllByApplicationId(@RequestParam("applicationId") String applicationId){
		return service.findAllByApplicationId(applicationId) ; 
	}
	
	@GetMapping("findAllByTenantId")
	List<E> findAllByTenantId(@RequestParam("tenantId") String tenantId){
		return service.findAllByTenantId(tenantId) ; 
	}
}
